﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SAKS.IServices;
using SAKS.ViewModels;
using SAKS.Models;
using NHibernate.Linq;

namespace SAKS.Services
{
    public class RoleServices : IRoleServices
    {

        public NHibernate.ISession Session { get; set; }

        public void AddUserToRole(string userName, string roleName)
        {
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(roleName))
                throw new ArgumentException("值不可以为空或\"null\".", "role or username");
            var user = Session.QueryOver<User>().Where(u => u.UserName == userName).SingleOrDefault();
            var role = Session.QueryOver<Role>().Where(r => r.RoleName == roleName).SingleOrDefault();
            user.Roles.Add(role);
            Session.Update(user);
        }

        public void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            if (usernames == null || usernames.Count() == 0) throw new ArgumentException("值不可以为空或\"null\".", "userNames");
            if (roleNames == null || roleNames.Count() == 0) throw new ArgumentException("值不可以为空或\"null\".", "roleNames");

            var users = new List<User>();
            foreach(var item in usernames)
            {
                users.Add(Session.QueryOver<User>().Where(u => u.UserName == item).SingleOrDefault());
            }
            var roles = new List<Role>();
            foreach (var item in roleNames)
            {
                roles.Add(Session.QueryOver<Role>().Where(r => r.RoleName == item).SingleOrDefault());
            }
            foreach (var user in users)
            {
                foreach(var role in roles)
                {
                    user.Roles.Add(role);
                }
                Session.Update(user);
            }

        }

        public IList<string> FindUsersInRole(string roleName, string usernameToMatch)
        {
            if (String.IsNullOrEmpty(roleName)) throw new ArgumentException("值不可以为空或\"null\".", "roleName");
            if (String.IsNullOrEmpty(usernameToMatch)) throw new ArgumentException("值不可以为空或\"null\".", "usernameToMatch");

            var query = from u in Session.Query<User>()
                        where u.Roles.Any(r => r.RoleName == roleName)
                        select u.UserName;
            return query.ToList<string>();
        }

        public IList<string> GetAllRoles()
        {
            var query = from r in Session.Query<Role>()
                        select r.RoleName;
            return query.ToList<string>();
        }

        public IList<string> GetRolesForUser(string username)
        {
            if (String.IsNullOrEmpty(username)) throw new ArgumentException("值不可以为空或\"null\".", "username");
            var roles = from r in Session.Query<Role>()
                        where r.Users.Any(u => u.UserName == username)
                        select r.RoleName;
            return roles.ToList<string>();
        }

        public IList<string> GetUsersInRole(string roleName)
        {
            if (String.IsNullOrEmpty(roleName)) throw new ArgumentException("值不可以为空或\"null\".", "roleName");
            var query = from u in Session.Query<User>()
                        where u.Roles.Any(
                            r => r.RoleName == roleName
                        )
                        select u.UserName;
            return query.ToList<string>();
        }

        public bool IsUserInRole(string username, string roleName)
        {
            if (String.IsNullOrEmpty(username)) throw new ArgumentException("值不可以为空或\"null\".", "username");
            if (String.IsNullOrEmpty(roleName)) throw new ArgumentException("值不可以为空或\"null\".", "roleName");
            var query = from u in Session.Query<User>()
                        where u.UserName == username && u.Roles.Any(
                            r => r.RoleName == roleName
                        )
                        select u.UserName;
            return query.SingleOrDefault() != null;
        }

        public void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            if (usernames == null || usernames.Count() == 0) throw new ArgumentException("值不可以为空或\"null\".", "userNames");
            if (roleNames == null || roleNames.Count() == 0) throw new ArgumentException("值不可以为空或\"null\".", "roleNames");

            var users = new List<User>();
            foreach (var item in usernames)
            {
                users.Add(Session.QueryOver<User>().Where(u => u.UserName == item).SingleOrDefault());
            }
            var roles = new List<Role>();
            foreach (var item in roleNames)
            {
                roles.Add(Session.QueryOver<Role>().Where(r => r.RoleName == item).SingleOrDefault());
            }

            foreach (var user in users)
            {
                foreach (var role in roles)
                {
                    user.Roles.Remove(role);
                }
                Session.Update(user);
            }
        }


        public bool RoleExists(string roleName)
        {
            if (String.IsNullOrEmpty(roleName)) throw new ArgumentException("值不可以为空或\"null\".", "roleName");
            var query = from r in Session.Query<Role>()
                        where r.RoleName == roleName
                        select r.RoleName;
            return query.SingleOrDefault() != null;
        }
    }
}
